home *** CD-ROM | disk | FTP | other *** search
/ The Arsenal Files 8 / The Arsenal Files Collection #8 (Arsenal Computer) (1996).ISO / g_quake / dmmde321.zip / COMBAT.QC < prev    next >
Text File  |  1996-08-12  |  11KB  |  365 lines

  1.  
  2. void() T_MissileTouch;
  3. void() info_player_start;
  4. void(entity targ, entity attacker) ClientObituary;
  5.  
  6. void() monster_death_use;
  7.  
  8. //============================================================================
  9.  
  10. /*
  11. ============
  12. CanDamage
  13.  
  14. Returns true if the inflictor can directly damage the target.  Used for
  15. explosions and melee attacks.
  16. ============
  17. */
  18. float(entity targ, entity inflictor) CanDamage =
  19. {
  20. // bmodels need special checking because their origin is 0,0,0
  21.     if (targ.movetype == MOVETYPE_PUSH)
  22.     {
  23.         traceline(inflictor.origin, 0.5 * (targ.absmin + targ.absmax), TRUE, self);
  24.         if (trace_fraction == 1)
  25.             return TRUE;
  26.         if (trace_ent == targ)
  27.             return TRUE;
  28.         return FALSE;
  29.     }
  30.     
  31.     traceline(inflictor.origin, targ.origin, TRUE, self);
  32.     if (trace_fraction == 1)
  33.         return TRUE;
  34.     traceline(inflictor.origin, targ.origin + '15 15 0', TRUE, self);
  35.     if (trace_fraction == 1)
  36.         return TRUE;
  37.     traceline(inflictor.origin, targ.origin + '-15 -15 0', TRUE, self);
  38.     if (trace_fraction == 1)
  39.         return TRUE;
  40.     traceline(inflictor.origin, targ.origin + '-15 15 0', TRUE, self);
  41.     if (trace_fraction == 1)
  42.         return TRUE;
  43.     traceline(inflictor.origin, targ.origin + '15 -15 0', TRUE, self);
  44.     if (trace_fraction == 1)
  45.         return TRUE;
  46.  
  47.     return FALSE;
  48. };
  49.  
  50.  
  51. /*
  52. ============
  53. Killed
  54. ============
  55. */
  56. void(entity targ, entity attacker) Killed =
  57. {
  58.     local entity oself;
  59.  
  60.     oself = self;
  61.     self = targ;
  62.     
  63.     if (self.health < -99)
  64.         self.health = -99;        // don't let sbar look bad if a player
  65.  
  66.     if (self.movetype == MOVETYPE_PUSH || self.movetype == MOVETYPE_NONE)
  67.     {    // doors, triggers, etc
  68.         self.th_die ();
  69.         self = oself;
  70.         return;
  71.     }
  72.  
  73.     self.enemy = attacker;
  74.  
  75. // bump the monster counter
  76.     if (self.flags & FL_MONSTER)
  77.     {
  78.         killed_monsters = killed_monsters + 1;
  79.         WriteByte (MSG_ALL, SVC_KILLEDMONSTER);
  80.  
  81.                 //*** All this added to give differing values for killing
  82.                 //*** monsters in mega scoring mode.
  83.                 //*** DMMODES change
  84.                 if (teamplay == 4)
  85.                 {
  86.                         if (self.classname == "monster_dog")
  87.                                 attacker.frags = attacker.frags + 1;
  88.                         else
  89.                         if (self.classname == "monster_army")
  90.                                 attacker.frags = attacker.frags + 2;
  91.                         else
  92.                         if (self.classname == "monster_demon1")
  93.                                 attacker.frags = attacker.frags + 6;
  94.                         else
  95.                         if (self.classname == "monster_enforcer")
  96.                                 attacker.frags = attacker.frags + 4;
  97.                         else
  98.                         if (self.classname == "monster_fish")
  99.                                 attacker.frags = attacker.frags + 1;
  100.                         else
  101.                         if (self.classname == "monster_hell_knight")
  102.                                 attacker.frags = attacker.frags + 7;
  103.                         else
  104.                         if (self.classname == "monster_knight")
  105.                                 attacker.frags = attacker.frags + 3;
  106.                         else
  107.                         if (self.classname == "monster_ogre")
  108.                                 attacker.frags = attacker.frags + 4;
  109.                         else
  110.                         if (self.classname == "monster_shalrath")
  111.                                 attacker.frags = attacker.frags + 8;
  112.                         else
  113.                         if (self.classname == "monster_shambler")
  114.                                 attacker.frags = attacker.frags + 10;
  115.                         else
  116.                         if (self.classname == "monster_tarbaby")
  117.                                 attacker.frags = attacker.frags + 3;
  118.                         else
  119.                         if (self.classname == "monster_vomit")
  120.                                 attacker.frags = attacker.frags + 3;
  121.                         else
  122.                         if (self.classname == "monster_wizard")
  123.                                 attacker.frags = attacker.frags + 3;
  124.                         else
  125.                         if (self.classname == "monster_zombie")
  126.                                 attacker.frags = attacker.frags + 3;
  127.                 }        
  128.         }
  129.  
  130.         //*** DMMODES
  131.         //*** Entire section added for differing scores for players
  132.         if ((self.classname == "player") && (teamplay == 4)
  133.             && (attacker != self))
  134.         {
  135.                                 if (self.items & IT_ROCKET_LAUNCHER)
  136.                                         attacker.frags = attacker.frags + 10;
  137.                                 else
  138.                                 if (self.items & IT_LIGHTNING)
  139.                                         attacker.frags = attacker.frags + 8;
  140.                                 else
  141.                                 if (self.items & IT_SUPER_NAILGUN)
  142.                                         attacker.frags = attacker.frags + 7;
  143.                                 else
  144.                                 if (self.items & IT_GRENADE_LAUNCHER)
  145.                                         attacker.frags = attacker.frags + 6;
  146.                                 else
  147.                                 if (self.items & IT_NAILGUN)
  148.                                         attacker.frags = attacker.frags + 5;
  149.                                 else
  150.                                 if (self.items & IT_SUPER_SHOTGUN)
  151.                                         attacker.frags = attacker.frags + 4;
  152.                                 else
  153.                                 if (self.items & IT_SHOTGUN)
  154.                                         attacker.frags = attacker.frags + 2;
  155.         }
  156.  
  157.     ClientObituary(self, attacker);
  158.     
  159.     self.takedamage = DAMAGE_NO;
  160.     self.touch = SUB_Null;
  161.  
  162.     monster_death_use();
  163.     self.th_die ();
  164.     
  165.     self = oself;
  166. };
  167.  
  168.  
  169. /*
  170. ============
  171. T_Damage
  172.  
  173. The damage is coming from inflictor, but get mad at attacker
  174. This should be the only function that ever reduces health.
  175. ============
  176. */
  177. void(entity targ, entity inflictor, entity attacker, float damage) T_Damage=
  178. {
  179.     local    vector    dir;
  180.     local    entity    oldself;
  181.     local    float    save;
  182.     local    float    take;
  183.  
  184.     if (!targ.takedamage)
  185.         return;
  186.  
  187. // used by buttons and triggers to set activator for target firing
  188.     damage_attacker = attacker;
  189.  
  190. // check for quad damage powerup on the attacker
  191.     if (attacker.super_damage_finished > time)
  192.         damage = damage * 4;
  193.  
  194. // save damage based on the target's armor level
  195.  
  196.     save = ceil(targ.armortype*damage);
  197.     if (save >= targ.armorvalue)
  198.     {
  199.         save = targ.armorvalue;
  200.         targ.armortype = 0;    // lost all armor
  201.         targ.items = targ.items - (targ.items & (IT_ARMOR1 | IT_ARMOR2 | IT_ARMOR3));
  202.     }
  203.     
  204.     targ.armorvalue = targ.armorvalue - save;
  205.     take = ceil(damage-save);
  206.  
  207. // add to the damage total for clients, which will be sent as a single
  208. // message at the end of the frame
  209. // FIXME: remove after combining shotgun blasts?
  210.     if (targ.flags & FL_CLIENT)
  211.     {
  212.         targ.dmg_take = targ.dmg_take + take;
  213.         targ.dmg_save = targ.dmg_save + save;
  214.         targ.dmg_inflictor = inflictor;
  215.     }
  216.  
  217. // figure momentum add
  218.     if ( (inflictor != world) && (targ.movetype == MOVETYPE_WALK) )
  219.     {
  220.         dir = targ.origin - (inflictor.absmin + inflictor.absmax) * 0.5;
  221.         dir = normalize(dir);
  222.         targ.velocity = targ.velocity + dir*damage*8;
  223.     }
  224.  
  225. // check for godmode or invincibility
  226.     if (targ.flags & FL_GODMODE)
  227.         return;
  228.     if (targ.invincible_finished >= time)
  229.     {
  230.         if (self.invincible_sound < time)
  231.         {
  232.             sound (targ, CHAN_ITEM, "items/protect3.wav", 1, ATTN_NORM);
  233.             self.invincible_sound = time + 2;
  234.         }
  235.         return;
  236.     }
  237.  
  238. // team play damage avoidance
  239. // *** Teamplay 3 added for dm modes patch *** //
  240.         if ( ( (teamplay == 1) || (teamplay == 3) )
  241.                && (targ.team > 0)&&(targ.team == attacker.team) )
  242.         return;
  243.         
  244. // do the damage
  245.     targ.health = targ.health - take;
  246.             
  247.     if (targ.health <= 0)
  248.     {
  249.         Killed (targ, attacker);
  250.         return;
  251.     }
  252.  
  253. // react to the damage
  254.     oldself = self;
  255.     self = targ;
  256.  
  257.     if ( (self.flags & FL_MONSTER) && attacker != world)
  258.     {
  259.     // get mad unless of the same class (except for soldiers)
  260.         // *** DM Modes changes this for monster deathmatch *** //
  261.         if (self != attacker && attacker != self.enemy)
  262.                 {                       
  263.                         if ( (self.classname != attacker.classname) 
  264.                         || (self.classname == "monster_army" )
  265.                         || (deathmatch > 3 ) )
  266.             {
  267.                 if (self.enemy.classname == "player")
  268.                     self.oldenemy = self.enemy;
  269.                 self.enemy = attacker;
  270.                 FoundTarget ();
  271.             }
  272.         }
  273.     }
  274.  
  275.     if (self.th_pain)
  276.     {
  277.         self.th_pain (attacker, take);
  278.     // nightmare mode monsters don't go into pain frames often
  279.         if (skill == 3)
  280.             self.pain_finished = time + 5;        
  281.     }
  282.  
  283.     self = oldself;
  284. };
  285.  
  286. /*
  287. ============
  288. T_RadiusDamage
  289. ============
  290. */
  291. void(entity inflictor, entity attacker, float damage, entity ignore) T_RadiusDamage =
  292. {
  293.     local    float     points;
  294.     local    entity    head;
  295.     local    vector    org;
  296.  
  297.     head = findradius(inflictor.origin, damage+40);
  298.     
  299.     while (head)
  300.     {
  301.         if (head != ignore)
  302.         {
  303.             if (head.takedamage)
  304.             {
  305.                 org = head.origin + (head.mins + head.maxs)*0.5;
  306.                 points = 0.5*vlen (inflictor.origin - org);
  307.                 if (points < 0)
  308.                     points = 0;
  309.                 points = damage - points;
  310.                 if (head == attacker)
  311.                     points = points * 0.5;
  312.                 if (points > 0)
  313.                 {
  314.                     if (CanDamage (head, inflictor))
  315.                     {    // shambler takes half damage from all explosions
  316.                         if (head.classname == "monster_shambler")                        
  317.                             T_Damage (head, inflictor, attacker, points*0.5);
  318.                         else
  319.                             T_Damage (head, inflictor, attacker, points);
  320.                     }
  321.                 }
  322.             }
  323.         }
  324.         head = head.chain;
  325.     }
  326. };
  327.  
  328. /*
  329. ============
  330. T_BeamDamage
  331. ============
  332. */
  333. void(entity attacker, float damage) T_BeamDamage =
  334. {
  335.     local    float     points;
  336.     local    entity    head;
  337.     
  338.     head = findradius(attacker.origin, damage+40);
  339.     
  340.     while (head)
  341.     {
  342.         if (head.takedamage)
  343.         {
  344.             points = 0.5*vlen (attacker.origin - head.origin);
  345.             if (points < 0)
  346.                 points = 0;
  347.             points = damage - points;
  348.             if (head == attacker)
  349.                 points = points * 0.5;
  350.             if (points > 0)
  351.             {
  352.                 if (CanDamage (head, attacker))
  353.                 {
  354.                     if (head.classname == "monster_shambler")                        
  355.                         T_Damage (head, attacker, attacker, points*0.5);
  356.                     else
  357.                         T_Damage (head, attacker, attacker, points);
  358.                 }
  359.             }
  360.         }
  361.         head = head.chain;
  362.     }
  363. };
  364.  
  365.